package com.szeldon.pj.jps.exp;

import com.szeldon.pj.jps.data.store.SBAStore;
import com.szeldon.pj.jps.datastore.SimpleObject;
import com.szeldon.pj.jps.envs.ENVS;
import com.szeldon.pj.jps.qres.AbstractQueryResult;
import com.szeldon.pj.jps.qres.IntegerResult;
import com.szeldon.pj.jps.qres.QResStack;
import com.szeldon.pj.jps.qres.RealResult;
import com.szeldon.pj.jps.visitor.ASTVisitor;

public class DivisionBinaryExpression extends BinaryExpression {

	/**
	 * 
	 * @param leftExpression
	 * @param rightExpression
	 */
	public DivisionBinaryExpression(Expression leftExpression, Expression rightExpression) {
		super(leftExpression, rightExpression);
	}

	@Override
	public int compareTo(SimpleObject object) throws IllegalStateException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String getValueAsString() {
		// TODO Auto-generated method stub
		return null;
	}

	public void accept(ASTVisitor astVisitor, ENVS envs, QResStack qResStack, SBAStore store) {

		astVisitor.accept(leftExpression);
		AbstractQueryResult leftResult = qResStack.pop();
		checkIfResultIsSupported(leftResult, "left");

		astVisitor.accept(rightExpression);
		AbstractQueryResult rightResult = qResStack.pop();
		checkIfResultIsSupported(rightResult, "right");

		double sum = 0;
		sum += getValueFromNumberResult(leftResult);
		sum /= getValueFromNumberResult(rightResult);

		AbstractQueryResult expressionResult = new RealResult(sum);

		qResStack.push(expressionResult);

	}

	private void checkIfResultIsSupported(AbstractQueryResult result, String typeOfResult) {
		if (!(result instanceof IntegerResult) && !(result instanceof RealResult)) {
			throw new IllegalStateException("Plus expression can't have " + result.getClass().getName() + " as "
					+ typeOfResult + " result.");
		}
	}

	private double getValueFromNumberResult(AbstractQueryResult result) {
		double value = 0;
		if (result instanceof RealResult) {
			value += ((RealResult) result).getReal();
		} else {
			value += ((IntegerResult) result).getInteger();
		}
		return value;
	}

}
